package com.ludomancy.sos64;

import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.Iterator;

import com.ludomancy.gamelib.Button;
import com.ludomancy.gamelib.Randomizer;
import com.ludomancy.gamelib.Widget;
import com.ludomancy.gamelib.Button.ButtonListener;

public class WorldWidget extends Widget implements ButtonListener
{
	private Component selected = null;
	private Component hovering = null;
	private Point selectedAnchor;
	private Accumulator shake;
	public Button reset;


	public WorldWidget(Widget parent, Rectangle area)
	{
		super(parent, area);
		reset = new Button(this, new Rectangle(0,area.height-21, area.width, 20), "Reboot", this);
	}
	
	public void onPress(Button widget)
	{
		if(widget == reset)
		{
			Sos64App.app.resetGame(false);
		}
	}

	public void startShake()
	{
		shake = new Accumulator(450);
	}
		
	public void update()
	{
		if(Game.game != null)
		{
			Game.game.update();
		}
	}
		
	public void paint(Graphics g)
	{
		// check that the selection still works
		if(selected != null && !Game.game.components.contains(selected))
		{
			selected = null;
		}
		int shakeAmount = 0;
		if(shake != null && shake.isRunning())
		{
			shakeAmount = Randomizer.getRandom(-3,3);
			g.translate(0, shakeAmount);
		}
		Game.game.terrain.paint(g);
		// draw components
		for (Iterator iterator = Game.game.components.iterator(); iterator.hasNext();)
		{
			Component c = (Component) iterator.next();
			if(c == hovering && selected == null)
			{
				g.translate(-1, -1);
			}
			c.paint(g);
			if(c == hovering && selected == null)
			{
				g.translate(1, 1);
			}
		}
		if(shake != null && shake.isRunning())
		{
			g.translate(0, -shakeAmount);
			shake.update();
		}
		if(selected != null)
		{
			selected.paint(g);
		}
	}
	
	public void mouseDown(Point pos)
	{
		Component c = Game.game.getComponent(pos.x, pos.y);
		if(c != null)
		{
			c.onClick(new Point(pos.x - c.x, pos.y - c.y));
		}
	}
	
	public Object beginDrag(Point cursor)
	{
		Component c = Game.game.getComponent(cursor.x, cursor.y);
		if(c != null && c.canMove())
		{
			selected = c;
			selectedAnchor = new Point(c.x - cursor.x, c.y - cursor.y);
			return c;
		}
		else
		{
			selected = null;
		}
		return null;
	}
	
	public void onDrag(Point cursor, Object object)
	{
		if(object instanceof Component)
		{
			Component c = (Component) object;
			Point desired = new Point(cursor.x + selectedAnchor.x, cursor.y + selectedAnchor.y);
			Point newpos = restrict(c, desired);
			Game.game.startMoving(c, newpos);
		}
	}
	
	private Point restrict(Component c, Point desired)
	{
		int x = Math.min(getWidth()-c.getSize().x - 5, Math.max(5, desired.x));
		int y = Math.min(getHeight()-c.getSize().y, Math.max(5, desired.y));
		
		if(c.snapToTile())
		{
			x = x/Game.TILE_WIDTH;
			y = y/Game.TILE_HEIGHT;
			
			x *= Game.TILE_WIDTH;
			y *= Game.TILE_HEIGHT;
		}
		
		return new Point(x,y);
	}

	public void onDrop(Widget issuer, Point cursor, Object dragObject)
	{
		if(dragObject instanceof Component)
		{
			Component c = (Component) dragObject;
			Game.game.finishMoving(c);
		}
		selected = null;
	}

	public void mouseMoved(Point point)
	{
		Component c = Game.game.getComponent(point.x, point.y);
		if(c != null && c.canMove())
		{
			hovering = c;
		}
		else
		{
			hovering = null;
		}
	}
}
